home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / russell / gc32.lha / dynamic_load.c < prev    next >
C/C++ Source or Header  |  1993-07-29  |  4KB  |  151 lines

  1. /*
  2.  * Copyright (c) 1991-1993 by Xerox Corporation.  All rights reserved.
  3.  *
  4.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  6.  *
  7.  * Permission is hereby granted to copy this garbage collector for any purpose,
  8.  * provided the above notices are retained on all copies.
  9.  * Author: Bill Janssen
  10.  * Modified by: Hans Boehm
  11.  */
  12.  
  13. /*
  14.  * This is incredibly OS specific code for tracking down data sections in
  15.  * dynamic libraries.  There appears to be no way of doing this quickly
  16.  * without groveling through undocumented data structures.  We would argue
  17.  * that this is a bug in the design of the dlopen interface.  THIS CODE
  18.  * MAY BREAK IN FUTURE OS RELEASES.  If this matters to you, don't hesitate
  19.  * to let your vendor know ...
  20.  */
  21. #include "gc_private.h"
  22. #ifdef DYNAMIC_LOADING
  23. #if !(defined(M68K) && defined(SUNOS)) && !defined(SPARC)
  24.  --> We only know how to find data segments of dynamic libraries under SunOS 4.X
  25. #endif
  26.  
  27. #include <stdio.h>
  28. #if defined SUNOS5
  29. #   include <sys/elf.h>
  30. #   include <dlfcn.h>
  31. #   include <link.h>
  32. #else
  33. #   include <dlfcn.h>
  34. #   include <link.h>
  35. #   include <a.out.h>
  36.   /* struct link_map field overrides */
  37. #   define l_next    lm_next
  38. #   define l_addr    lm_addr
  39. #   define l_name    lm_name
  40. # endif
  41.  
  42.  
  43. #ifdef SUNOS5
  44.  
  45. #ifdef LINT
  46.     Elf32_Dyn _DYNAMIC;
  47. #endif
  48.  
  49. static struct link_map *
  50. GC_FirstDLOpenedLinkMap()
  51. {
  52.     extern Elf32_Dyn _DYNAMIC;
  53.     Elf32_Dyn *dp;
  54.     struct r_debug *r;
  55.     static struct link_map * cachedResult = 0;
  56.  
  57.     if( &_DYNAMIC == 0) {
  58.         return(0);
  59.     }
  60.     if( cachedResult == 0 ) {
  61.         int tag;
  62.         for( dp = ((Elf32_Dyn *)(&_DYNAMIC)); (tag = dp->d_tag) != 0; dp++ ) {
  63.             if( tag == DT_DEBUG ) {
  64.                 struct link_map *lm
  65.                         = ((struct r_debug *)(dp->d_un.d_ptr))->r_map;
  66.                 if( lm != 0 ) cachedResult = lm->l_next; /* might be NIL */
  67.                 break;
  68.             }
  69.         }
  70.     }
  71.     return cachedResult;
  72. }
  73.  
  74. # endif
  75.  
  76. # ifdef SUNOS4
  77.  
  78. #ifdef LINT
  79.     struct link_dynamic _DYNAMIC;
  80. #endif
  81.  
  82. static struct link_map *
  83. GC_FirstDLOpenedLinkMap()
  84. {
  85.     extern struct link_dynamic _DYNAMIC;
  86.  
  87.     if( &_DYNAMIC == 0) {
  88.         return(0);
  89.     }
  90.     return(_DYNAMIC.ld_un.ld_1->ld_loaded);
  91. }
  92.  
  93.  
  94. # endif
  95.  
  96. /* Add dynamic library data sections to the root set.        */
  97. # if !defined(PCR) && defined(THREADS)
  98.     --> fix mutual exclusion with dlopen
  99. # endif
  100. void GC_register_dynamic_libraries()
  101. {
  102.   struct link_map *lm = GC_FirstDLOpenedLinkMap();
  103.   
  104.  
  105.   for (lm = GC_FirstDLOpenedLinkMap();
  106.        lm != (struct link_map *) 0;  lm = lm->l_next)
  107.     {
  108. #     ifdef SUNOS4
  109.     struct exec *e;
  110.      
  111.         e = (struct exec *) lm->lm_addr;
  112.         GC_add_roots_inner(
  113.                   ((char *) (N_DATOFF(*e) + lm->lm_addr)),
  114.             ((char *) (N_BSSADDR(*e) + e->a_bss + lm->lm_addr)));
  115. #     endif
  116. #     ifdef SUNOS5
  117.     Elf32_Ehdr * e;
  118.         Elf32_Phdr * p;
  119.         unsigned long offset;
  120.         char * start;
  121.         register int i;
  122.         
  123.     e = (Elf32_Ehdr *) lm->l_addr;
  124.         p = ((Elf32_Phdr *)(((char *)(e)) + e->e_phoff));
  125.         offset = ((unsigned long)(lm->l_addr));
  126.         for( i = 0; i < (int)(e->e_phnum); ((i++),(p++)) ) {
  127.           switch( p->p_type ) {
  128.             case PT_LOAD:
  129.               {
  130.                 if( !(p->p_flags & PF_W) ) break;
  131.                 start = ((char *)(p->p_vaddr)) + offset;
  132.                 GC_add_roots_inner(
  133.                   start,
  134.                   start + p->p_memsz
  135.                 );
  136.               }
  137.               break;
  138.             default:
  139.               break;
  140.           }
  141.     }
  142. #     endif
  143.     }
  144. }
  145.  
  146. #else
  147. void GC_register_dynamic_libraries(){}
  148.  
  149. int GC_no_dynamic_loading;
  150. #endif
  151.